/**
 * Created by Ysssssss on 2021/4/28.
 */

import React, {forwardRef, useState, useEffect, useCallback, useContext, useRef} from 'react'
import { Checkbox, Button, Select } from "antd";
import CustomizeModal, {CustomizeModalContext} from "@common/presentational/CustomizeModal";
import {useDispatch, useSelector} from "react-redux";
import {getStoreSelection} from "@sagas/storeManagement";
import SearchInput from "@common/presentational/SearchInput";
import {getProductSelection, getProductTypeSelection} from "@sagas/productCenter";
import {arrayToObject} from "@utils/arrayHelper";
import {priceRangePreview} from "@utils/priceConversion";
import {
    getCanImportToShelfProductSelection,
    getShelfGroupList,
    getShelfProductSelection,
} from "@sagas/shoppingMall/shoppingMallProduct";
import getCdnUrl from "@utils/getCdnUrl";
import BilinIcon from "@common/presentational/BilinIcon";
import notify from "@utils/tip";
import {CloseOutlined} from "@ant-design/icons";

let pageSize = 50

// 商品选择框
const MultiSelectProductContent = props => {
    const { initSelectedInfo, onChange, productSelectionPagination, productTypeSelection, keyProps = 'id' } = props
    const [ current, setCurrent ] = useState(1)
    const [ { query, productType }, setParams ] = useState({ query: '', productType: '' })
    const [ selectedInfo, setSelectedInfo ] = useState(initSelectedInfo || [])
    const dispatch = useDispatch()
    const { hide } = useContext(CustomizeModalContext)

    const selectedInfoMap = useCallback(arrayToObject(selectedInfo, keyProps), [selectedInfo])

    useEffect(() => {
        dispatch(props.getProductTypeSelection())
    }, [])

    useEffect(() => {
        dispatch(props.getProductSelection({
            pageNo: current,
            pageSize,
            prodTypeId: productType,
            query
        }))
    }, [productType, query, current])

    const handleValueChange = useCallback((key, value) => {
        setParams({
            query,
            productType,
            [key]: value
        })
        setCurrent(1)
    }, [query, productType])

    const handleSelectedInfoChange = useCallback(prod => {
        if (selectedInfoMap[prod[keyProps]]) {
            setSelectedInfo(selectedInfo.filter(item => item[keyProps] !== prod[keyProps]))
        } else {
            setSelectedInfo([
                ...selectedInfo,
                prod
            ])
        }
    }, [selectedInfo])

    const cancelStoreSelected = useCallback(index => {
        setSelectedInfo([
            ...selectedInfo.slice(0, index),
            ...selectedInfo.slice(index + 1)
        ])
    }, [selectedInfo])

    const selectAll = useCallback(e => {
        const checked = e.target.checked
        if (checked) {
            setSelectedInfo([
                ...selectedInfo,
                ...(productSelectionPagination.prods || []).filter(prod => !selectedInfoMap[prod[keyProps]])
            ])
        } else {
            setSelectedInfo(_.differenceWith(selectedInfo, (productSelectionPagination.prods || []), (a,b) => b[keyProps] === a[keyProps]))
        }
    }, [selectedInfo, productSelectionPagination])

    const selectedSubmit = useCallback(() => {
        if (!selectedInfo.length) {
            notify('请选择商品')
            return ;
        }
        onChange && onChange(selectedInfo);
        hide()
    }, [onChange, selectedInfo])

    const handleScroll = useCallback(e => {
        if (e.target.scrollHeight - e.target.scrollTop - e.target.clientHeight < 100) {
            if (current === productSelectionPagination.pageNo &&
                productSelectionPagination.prods.length < productSelectionPagination.total
            ) {
                setCurrent(current + 1)
            }
        }
    }, [current, productSelectionPagination])

    return (
        <>
            <div className="multi-select-body">
                <div className="multi-select-left">
                    <div className="page-params flex-vertical-center">
                        <Select className="mgr-16"
                                style={{width: '160px'}}
                                onChange={handleValueChange.bind(this, 'productType')}
                                value={productType}
                        >
                            <Select.Option key="all" value="">全部</Select.Option>
                            { productTypeSelection.map(productTypeGroup => productTypeGroup.subs && productTypeGroup.subs.length ? (
                                <Select.OptGroup key={productTypeGroup.id} label={productTypeGroup.name}>
                                    { productTypeGroup.subs.map(productType => (
                                        <Select.Option
                                            key={productType.id}
                                            value={productType.id}
                                        >
                                            { productType.name }
                                        </Select.Option>
                                    )) }
                                </Select.OptGroup>
                            ) : (
                                <Select.Option
                                    key={productTypeGroup.id}
                                    value={productTypeGroup.id}
                                >
                                    { productTypeGroup.name }
                                </Select.Option>
                            ))}
                        </Select>
                        <SearchInput
                            style={{width: '376px'}}
                            onChange={handleValueChange.bind(this, 'query')}
                            initValue={query}
                            value={query}
                            placeholder="商品名称"
                        />
                    </div>
                    <div className="item-selected-container" onScroll={handleScroll}>
                        { (productSelectionPagination.prods || []).map(prod => (
                            <div className={`product-box${selectedInfoMap[prod[keyProps]] ? ' selected' : ''}`}
                                 key={prod[keyProps]}
                                 onClick={handleSelectedInfoChange.bind(this, prod)}
                            >
                                <img src={getCdnUrl(prod.title_pic)} alt="" className="product-pic"/>
                                <div className="product-name">{ prod.custom_name || prod.name }</div>
                                <div className="product-price">{priceRangePreview(prod.price_range)}</div>
                                <Checkbox className="checkbox-icon" checked={selectedInfoMap[prod[keyProps]]}/>
                            </div>
                        )) }
                    </div>
                </div>
                <div className="multi-select-right">
                    <div className="ft-clr-md ft-12">已选商品（{selectedInfo.length}）</div>
                    { selectedInfo.map((prod, index) => (
                        <div className="select-line" key={prod[keyProps]}>
                            <span>{prod.custom_name || prod.name}</span>
                            <BilinIcon type="design-delete" onClick={cancelStoreSelected.bind(this, index)}/>
                        </div>
                    )) }
                </div>
            </div>
            <div className="multi-select-footer">
                <Checkbox onChange={selectAll.bind(this)} checked={_.differenceWith((productSelectionPagination.prods || []), selectedInfo, (a,b) => a[keyProps] === b[keyProps]).length === 0}>全选</Checkbox>
                <Button className="button-large" type="primary" onClick={selectedSubmit.bind(this)}>选好了</Button>
            </div>
        </>
    )
}

// 从商品库选择商品
export const MultiSelectProductModal = forwardRef(({ title, excludedMenuId = 0, ...props }, ref) => {
    const { productSelectionPagination, productTypeSelection } = useSelector(state => state.productCenter)
    const _getProductSelection = useCallback(params =>
        getProductSelection({
            ...params,
            excludedMenuId
        }), [excludedMenuId]
    )
    return (
        <CustomizeModal title={title} className="multi-select-modal" width={820} ref={ref}>
            <MultiSelectProductContent
                {...props}
                productSelectionPagination={productSelectionPagination}
                productTypeSelection={productTypeSelection}
                getProductSelection={_getProductSelection}
                getProductTypeSelection={getProductTypeSelection}
            />
        </CustomizeModal>
    )
})

// 从供货组或者商品库选择可上架商城商品
export const MultiSelectShoppingMallImportProductModal = forwardRef(({ title, ...props }, ref) => {
    const { productTypeSelection } = useSelector(state => state.productCenter)
    const { productCanImportListPagination } = useSelector(state => state.shoppingMallProduct)
    const { fromMenu } = props
    const _getProductSelection = useCallback(params =>
        getCanImportToShelfProductSelection({
            ...params,
            fromMenu
        }), [fromMenu]
    )
    const _getProductTypeSelection = useCallback(() =>
        getProductTypeSelection(fromMenu ? {
            pStoreId: 0
        } : {}), [fromMenu]
    )
    return (
        <CustomizeModal title={title} className="multi-select-modal" width={820} ref={ref}>
            <MultiSelectProductContent
                {...props}
                productSelectionPagination={productCanImportListPagination}
                productTypeSelection={productTypeSelection}
                getProductSelection={_getProductSelection}
                getProductTypeSelection={_getProductTypeSelection}
            />
        </CustomizeModal>
    )
})

// 选择商城货架商品
export const MultiSelectShelfProductModal = forwardRef(({ title, ...props }, ref) => {
    const { shelfGroupList, shelfProductSelectionPagination } = useSelector(state => state.shoppingMallProduct)
    const _getShelfProductList = useCallback(({prodTypeId, ...params}) =>
        getShelfProductSelection({
            ...params,
            groupId: prodTypeId
        }), []
    )
    return (
        <CustomizeModal title={title} className="multi-select-modal" width={820} ref={ref}>
            <MultiSelectProductContent
                {...props}
                productSelectionPagination={shelfProductSelectionPagination}
                productTypeSelection={shelfGroupList}
                getProductSelection={_getShelfProductList}
                getProductTypeSelection={getShelfGroupList}
            />
        </CustomizeModal>
    )
})

// 选择商城货架商品-拉平至规格
export const MultiSelectShelfSkuProductModal = forwardRef(({ title, ...props }, ref) => {
    const { shelfGroupList, shelfSkuProductSelectionPagination } = useSelector(state => state.shoppingMallProduct)
    const _getShelfProductList = useCallback(({prodTypeId, ...params}) =>
        getShelfProductSelection({
            ...params,
            groupId: prodTypeId
        }), []
    )
    return (
        <CustomizeModal title={title} className="multi-select-modal" width={820} ref={ref}>
            <MultiSelectProductContent
                {...props}
                productSelectionPagination={shelfSkuProductSelectionPagination}
                productTypeSelection={shelfGroupList}
                getProductSelection={_getShelfProductList}
                getProductTypeSelection={getShelfGroupList}
                keyProps="storage_key"
            />
        </CustomizeModal>
    )
})

// 门店选择框
const MultiSelectStoreContent = props => {
    const { onChange } = props
    const { hide, params } = useContext(CustomizeModalContext)
    const { initSelectedStores} = params
    const [ query, setQuery ] = useState('')
    const [ selectedStores, setSelectedStores ] = useState(initSelectedStores || [])
    const [ storeSelectionFiltered, setStoreSelectionFiltered ] = useState([])
    const dispatch = useDispatch()
    const { storeSelection, storeMap } = useSelector(state => state.storeManagement)

    const selectedStoresMap = useCallback(arrayToObject(selectedStores, 'store_id'), [selectedStores])

    useEffect(() => {
        dispatch(getStoreSelection())
    }, [])

    useEffect(() => {
        setStoreSelectionFiltered(
            storeSelection.filter(store => store.store_name.includes(query))
        )
    }, [storeSelection, query])


    const handleQueryChange = useCallback(value => {
        setQuery(value)
    }, [])

    const handelSelectStoresChange = useCallback(store => {
        setSelectedStores(selectedStoresMap[store.store_id] ?
            selectedStores.filter(item => item.store_id !== store.store_id) :
            [...selectedStores, store])
    }, [selectedStores])

    const cancelStoreSelected = useCallback(index => {
        setSelectedStores([
            ...selectedStores.slice(0, index),
            ...selectedStores.slice(index + 1)
        ])
    }, [selectedStores])

    const selectAll = useCallback(e => {
        const checked = e.target.checked
        if (checked) {
            setSelectedStores([
                ...selectedStores,
                ...(storeSelectionFiltered || []).filter(store => !selectedStoresMap[store.store_id])
            ])
        } else {
            setSelectedStores(_.differenceWith(selectedStores, (storeSelectionFiltered || []), (a,b) => b.store_id === a.store_id))
        }
    }, [selectedStores, storeSelectionFiltered, selectedStoresMap])

    const selectedSubmit = () => {
        if (!selectedStores.length) {
            notify('请选择店铺')
            return ;
        }
        onChange && onChange(selectedStores, params);
        hide()
    }

    return (
        <>
            <div className="multi-select-body">
                <div className="multi-select-left">
                    <div className="page-params">
                        <SearchInput
                            style={{width: '100%'}}
                            onChange={handleQueryChange.bind(this)}
                            initValue={query}
                            value={query}
                            placeholder="店铺名称"
                        />
                    </div>
                    <div className="item-selected-container">
                        { storeSelectionFiltered.map(store => (
                            <div className={`store-box${selectedStoresMap[store.store_id] ? ' selected' : ''}`}
                                 key={store.store_id}
                                 onClick={handelSelectStoresChange.bind(this, store)}
                            >{ store.store_name }</div>
                        )) }
                    </div>
                </div>
                <div className="multi-select-right">
                    <div className="ft-clr-md ft-12">已选店铺（{selectedStores.length}）</div>
                    { selectedStores.map((store, index) => (
                        <div className="select-line" key={store.store_id}>
                            <span>{store.store_name}</span>
                            <BilinIcon type="design-delete" onClick={cancelStoreSelected.bind(this, index)}/>
                        </div>
                    )) }
                </div>
            </div>
            <div className="multi-select-footer">
                <Checkbox onChange={selectAll.bind(this)} checked={_.differenceWith(storeSelectionFiltered, selectedStores, (a,b) => a.store_id === b.store_id).length === 0}>全选</Checkbox>
                <Button className="button-large" type="primary" onClick={selectedSubmit.bind(this)}>选好了</Button>
            </div>
        </>
    )
}

export const MultiSelectStoreModal = forwardRef(({ title, ...props }, ref) => {
    return (
        <CustomizeModal title={title} className="multi-select-modal" width={820} ref={ref}>
            <MultiSelectStoreContent {...props}/>
        </CustomizeModal>
    )
})

export const MultiSelectStoreContainer = props => {
    const { onChange, value, className } = props
    const multiSelectStoreModalRef = useRef()

    const showMultiSelectModal = useCallback(() => {
        multiSelectStoreModalRef.current?.show({
            initSelectedStores: value,
        })
    }, [value])

    const deleteStore = useCallback((index) => {
        onChange && onChange([
            ...value.slice(0, index),
            ...value.slice(index + 1)
        ])
    }, [value])

    return (
        <div className={className}>
            <Button className="button-small" type="primary" ghost onClick={showMultiSelectModal}>+ 选择店铺</Button>
            { value.length ? (
                <div className="multi-select-preview-list mgt-16">
                    { value.map((item, index) => (
                        <div key={item.store_id} className="multi-select-preview-item">
                            <span>{ item.store_name }</span>
                            <CloseOutlined className="delete-icon" onClick={deleteStore.bind(this, index)} />
                        </div>
                    )) }
                </div>
            ) : null }
            <MultiSelectStoreModal
                ref={multiSelectStoreModalRef}
                title="应用店铺"
                onChange={onChange}
            />
        </div>
    )
}